#ifndef EVENT_TIMERTASK_H_
#define EVENT_TIMERTASK_H_
#include <fermat/common/timestamp.h>
#include <fermat/common/atomic.h>
#include <functional>
#include <cstdint>



namespace fermat {
namespace event {

typedef std::function<void()> TimerCallback;

class TimerTask {
public:
    TimerTask(const TimerCallback& cb, const fermat::Timestamp& when,
                  const int64_t& interval)
      : _callback(cb),
        _expiration(when),
        _interval(interval),
        _repeat(interval > 0),
        _sequence(_gTimerNum.fetch_increment())
    { }

   void run() const
   {
      _callback();
   }

    fermat::Timestamp& expiration()  { return _expiration; }
    bool repeat() const { return _repeat; }
    int64_t sequence() const { return _sequence; }

    void restart(const fermat::Timestamp &now);

    int64_t step() const { return _interval; }
    
    static int64_t numCreated() { return _gTimerNum.load(); }
private:
    const TimerCallback _callback;
    fermat::Timestamp _expiration;
    const int64_t _interval;
    const bool _repeat;
    const int64_t _sequence;

    static fermat::atomic_int64 _gTimerNum;
};

}
}

#endif
